<template>
    <div class="settle-game" :style="shouldShowContent ? backgroundImageStyle : {}">
        <!-- 背景框 -->
        <div v-if="shouldShowContent" class="background-container">
            <img v-if="props.leaderboardType === 'game'" :src="getImageUrl('backgroundBox_round.png')" alt="" class="background-image">
            <img v-else-if="props.leaderboardType === 'week'" :src="getImageUrl('backgroundBox_week.png')" alt="" class="background-image">
            <img v-else-if="props.leaderboardType === 'season'" :src="getImageUrl('backgroundBox_month.png')" alt="" class="background-image">
            <img v-else-if="props.leaderboardType === 'settlement'" :src="getImageUrl('backgroundBox.png')" alt="" class="background-image">
            <!-- 加载状态 -->
            <div v-if="isLoading" class="loading-state">
                <div class="loading-spinner"></div>
                <div class="loading-text">正在加载排行榜...</div>
            </div>
        </div>

        <!-- 内容容器 -->
        <div v-if="shouldShowContent" class="content-container">
            <!-- 排行类型切换按钮：赛季 / 本周 / 本局 -->
            <button
                class="lb-switch-btn switch-season"
                :style="switchButtonStyle('season')"
                @click="switchType('season')"
            >赛季</button>
            <button
                class="lb-switch-btn switch-week"
                :style="switchButtonStyle('week')"
                @click="switchType('week')"
            >本周</button>
            <button
                class="lb-switch-btn switch-game"
                :style="switchButtonStyle('game')"
                @click="switchType('game')"
            >本局</button>

            <!-- 关闭按钮：右上角红色圆形按钮 -->
            <button
                class="close-btn-floating"
                aria-label="关闭"
                @click="emit('display-completed', [])"
            >×</button>

            <!-- 游戏表格 -->
            <table v-if="!isLoading && allPlayers.length > 0 || props.leaderboardType === 'season' || props.leaderboardType === 'week'" class="game-table" ref="gameTable">
                <thead>
                    <tr>
                        <th class="victory-text" colspan="5">
                            <!-- 根据排行榜类型显示不同内容 -->
                            <span v-if="props.leaderboardType === 'season'">
                                S{{ currentSeasonNumber || props.season }} 排行榜
                            </span>
                            <span v-else-if="props.leaderboardType === 'week'">
                                本周排行榜
                            </span>
                            <span v-else-if="props.leaderboardType === 'game'">
                                本局排行榜
                            </span>
                            <!-- 结算模式显示胜利信息 -->
                            <span v-else-if="props.leaderboardType === 'settlement' && props.winTeam === 'red'">
                                🔴 Red Team Win!
                            </span>
                            <span v-else-if="props.leaderboardType === 'settlement' && props.winTeam === 'blue'">
                                🔵 Blue Team Win!
                            </span>
                            <!-- 兼容旧版本：其他情况下仍显示胜利信息 -->
                            <span v-else-if="props.winTeam === 'red'">
                                🔴 Red Team Win!
                            </span>
                            <span v-else-if="props.winTeam === 'blue'">
                                🔵 Blue Team Win!
                            </span>
                        </th>
                    </tr>
                    <tr>
                        <img :src="gameLogo" class="game-logo" alt="logo">
                        <td colspan="4">
                            <InfoBadge :topPlayers="topPlayers" :leaderboardType="props.leaderboardType" :game_id="props.gameId" />
                        </td>
                    </tr>
                    <tr>
                        <th class="header-rank">Rank</th>
                        <th class="header-avatar">Player</th>
                        <th class="header-name"></th>
                        <th class="header-units">
                            <span v-if="props.leaderboardType === 'season' || props.leaderboardType === 'week'">Score</span>
                            <span v-else>Units</span>
                        </th>
                        <th class="header-total-score" v-show="props.leaderboardType !== 'season' && props.leaderboardType !== 'week'">Total Score</th>
                        <th class="header-country" v-show="props.leaderboardType === 'season' || props.leaderboardType === 'week'">Country</th>
                    </tr>
                </thead>
                <tbody>
                    <tr class="player-row" v-for="(player, index) in currentPagePlayers"
                        :key="`${player.player_id}-${currentPage}`" :style="{
                            animationDelay: `${1.0 + index * 0.1}s`,
                        }">
                        <td class="player-rank"
                            :class="{ 'rank-with-bg': (currentPage * playersPerPage + index) < 3 && allPlayers.length > (currentPage * playersPerPage + index) }">
                            <img v-if="(currentPage * playersPerPage + index) < 3 && allPlayers.length > (currentPage * playersPerPage + index)"
                                :src="(currentPage * playersPerPage + index) == 0 ? rank1 : (currentPage * playersPerPage + index) == 1 ? rank2 : rank3"
                                alt="" class="rank-bg">
                            <span 
                                class="rank-number"
                                :class="{ 'top-3': currentPage * playersPerPage + index + 1 <= 3 }"
                                >{{ currentPage * playersPerPage + index + 1 }}</span>
                        </td>
                        <td class="player-avatar">
                            <img :style="{
                                backgroundColor: `rgba(${rowColors[index].r}, ${rowColors[index].g}, ${rowColors[index].b})`
                            }" :src="player.avatar || avatar" :alt="player.player_name"
                                @error="($event.target as HTMLImageElement).src = avatar">
                        </td>
                        <td class="player-name">
                            <span class="name-text">{{ player.player_name }}</span>
                        </td>
                        <td class="player-units">
                            <span class="animated-number" :class="{ 'animate-progress': true }" :style="{
                                borderColor: `rgb(${rowColors[index].r}, ${rowColors[index].g}, ${rowColors[index].b})`,
                                '--progress-color': `rgb(${rowColors[index].r}, ${rowColors[index].g}, ${rowColors[index].b})`,
                                '--progress-scale': calculateProgressScale(
                                    (props.leaderboardType === 'season' || props.leaderboardType === 'week') ? ((player as any).points || 0) : (player.units || 0),
                                    props.leaderboardType
                                )
                            }">
                                {{ getUnitsValue(player) }}
                            </span>
                        </td>
                        <td class="player-total-score" v-show="props.leaderboardType !== 'season' && props.leaderboardType !== 'week'">
                            <span class="animated-number">{{ getScoreValue(player) }}</span>
                        </td>
                        <td class="player-country" v-show="props.leaderboardType === 'season' || props.leaderboardType === 'week'">
                            <span class="country-text">{{ (player as any).country_name || '—' }}</span>
                        </td>
                    </tr>
                </tbody>
            </table>

            <!-- 独立的空状态显示 -->
            <div v-if="!isLoading && shouldShowContent && allPlayers.length === 0" class="empty-state">
                <div class="empty-icon">📊</div>
                <div class="empty-text">
                    <span v-if="props.leaderboardType === 'season'">暂无赛季排行榜数据</span>
                    <span v-else-if="props.leaderboardType === 'week'">暂无本周排行榜数据</span>
                    <span v-else-if="props.leaderboardType === 'game'">暂无本局排行榜数据</span>
                    <span v-else-if="props.leaderboardType === 'settlement'">暂无结算数据</span>
                    <span v-else>暂无排行榜数据</span>
                </div>
            </div>
        </div> <!-- 结束 content-container -->

        <!-- 分页指示器 -->
        <div v-if="totalPages > 1 && shouldShowContent" class="pagination-indicator">
            <div class="page-dots">
                <div
                    v-for="page in totalPages"
                    :key="page"
                    class="dot"
                    :class="{ active: page - 1 === currentPage }"
                    @click="goToPage(page - 1)"
                ></div>
            </div>
            <span class="page-info">{{ currentPage + 1 }} / {{ totalPages }}</span>
        </div>
    </div>
</template>

<script lang="ts" setup>
import { defineOptions, ref, onMounted, reactive, computed, onUnmounted, watch, nextTick, toRaw } from 'vue'
import eventBus from 'vue3-eventbus'
import postApi from '@/api/modules/post'
import getApi from '@/api/modules/get'
import type { Props } from '@/assets/common/types/Leaderboard'
import { calculatePlayerScores } from '@/utils/scoreCalculator'
import InfoBadge from './InfoBadge.vue'
import gameLogo from '@/assets/xinJi/images/gameLogo.png'

defineOptions({ name: 'XinJiLeaderboard' })

function getImageUrl(imageName: string) {
    return new URL(`../../assets/xinJi/images/leaderboard/${imageName}`, import.meta.url).href
}

// 使用computed来获取图片，这样可以在模板中直接使用
const rank1 = computed(() => getImageUrl('1.png'))
const rank2 = computed(() => getImageUrl('2.png'))
const rank3 = computed(() => getImageUrl('3.png'))
const avatar = computed(() => getImageUrl('avatar.png'))

const props = withDefaults(defineProps<Props>(), {
    leftPlayer: () => [],
    rightPlayer: () => [],
    messages: () => [],
    pointPool: 0,
    winTeam: '',
    visible: false,
    leaderboardType: 'game',
    gameId: 1,
    season: undefined,
    anchorId: '',
    redHpCurrent: 0,
    redName: '',
    blueHpCurrent: 0,
    blueName: ''
})

// 定义emit事件
const emit = defineEmits<{
    'display-completed': [playerResults: any[]]
}>()

// 新增一个周期ID，防止异步操作冲突
const displayCycleId = ref(0);

// 赛季数据状态
const seasonLeaderboardData = ref([]);
const currentSeasonNumber = ref(null);
const isLoading = ref(false);

// 本周排行榜数据状态
const weekLeaderboardData = ref([]);
const currentWeekRange = ref(null);

// 指令的显示状态
const isDirectiveVisible = ref(true);

const gameTable = ref<HTMLElement>()

const topPlayers = ref()

// 获取赛季排行榜数据
const fetchSeasonLeaderboard = async () => {
    const currentCycleId = displayCycleId.value; // 捕获当前周期ID
    isLoading.value = true;
    try {
        const params: any = {
            game_id: props.gameId,
            limit: 30
        };
        if (props.season) {
            params.season = props.season;
        }

        const response = await getApi.getSeasonLeaderboard(params);
        if (currentCycleId !== displayCycleId.value) return; // 如果周期已变，则中止旧的更新

        if (response && response.data) {
            seasonLeaderboardData.value = response.data.data || [];
            currentSeasonNumber.value = response.data.current_season;
        }
    } catch (error) {
        console.error('获取赛季排行榜失败:', error);
        seasonLeaderboardData.value = [];
        currentSeasonNumber.value = null;
    } finally {
        if (currentCycleId === displayCycleId.value) { // 仅在当前周期内更新加载状态
            isLoading.value = false;
        }
    }
};

// 获取本周排行榜数据
const fetchWeekLeaderboard = async () => {
    const currentCycleId = displayCycleId.value; // 捕获当前周期ID
    isLoading.value = true;
    try {
        const params: any = {
            game_id: props.gameId,
            limit: 30 // 默认获取前30名
        };

        const response = await getApi.getWeekLeaderboard(params);
        if (currentCycleId !== displayCycleId.value) return; // 如果周期已变，则中止旧的更新

        if (response && response.data) {
            weekLeaderboardData.value = response.data.data || [];
            currentWeekRange.value = response.data.week_range;
        }
    } catch (error) {
        console.error('获取本周排行榜失败:', error);
        weekLeaderboardData.value = [];
        currentWeekRange.value = null;
    } finally {
        if (currentCycleId === displayCycleId.value) { // 仅在当前周期内更新加载状态
            isLoading.value = false;
        }
    }
};

// 背景图片样式 - 使用动态导入
const backgroundImageStyle = computed(() => ({
    backgroundImage: `url(${getImageUrl('background.png')})`,
    backgroundSize: '1411px 1058px',
    backgroundRepeat: 'no-repeat',
    backgroundPosition: 'center'
}))

// 计算最终积分的函数
const calculateFinalScores = () => {
    return calculatePlayerScores(
        [...props.leftPlayer, ...props.rightPlayer],
        props.messages,
        props.winTeam,
        props.pointPool,
        'xinJi结算',  // 改为"xinJi结算"以区分预估模式
        true         // 结算模式，发送消息给Qt
    );
}

// 生成用户结算信息数组
const generatePlayerResults = () => {
    const playersWithFinalScores = calculateFinalScores()

    return playersWithFinalScores.map(player => {
        // 从 messages 中找到该玩家的信息
        const playerMessages = props.messages.filter(msg => msg.player_id === player.player_id)

        // 获取第一条消息中的基础信息，如果没有则使用默认值
        const baseMessage = playerMessages[0] || {}

        return {
            uuid: (baseMessage as any).uuid || '',                      // 对局ID
            game_id: (baseMessage as any).game_id || 1,                 // 游戏ID，默认为1
            userid_platform: player.userid_platform,                    // 平台用户ID
            avatar: player.avatar || '',                                // 用户头像
            player_name: player.player_name,                            // 用户名字
            point: (player as any).finalScore || 0,                     // 最终积分
            team: player.team,                                          // 队伍信息
            race: player.team == 'red' ? props.redName : props.blueName,// 玩家所属种族
            units: player.units || 0,                                   // 单位数
            is_winner: (player.team === props.winTeam),                 // 是否胜利
            is_test: props.anchorId == '111admin' || props.anchorId == '222admin',  // 是否测试
        }
    }).filter(result => result.point > 0)               // 只保留有积分的玩家
}

// 计算本局排行榜的结算积分
const gameLeaderboardScores = computed(() => {
    if (props.leaderboardType !== 'game' || props.messages.length === 0) {
        return new Map()
    }
    
    // 根据血量判断当前优势队伍
    let effectiveWinTeam: string | null = null
    if (props.redHpCurrent && props.blueHpCurrent) {
        if (props.redHpCurrent > props.blueHpCurrent) {
            effectiveWinTeam = 'red'
        } else if (props.blueHpCurrent > props.redHpCurrent) {
            effectiveWinTeam = 'blue'
        }
        // 血量相等时保持为null，按50%/50%分配
    }
    
    // 构建包含team信息的玩家数组
    const allPlayers: any[] = []
    for (const player of props.leftPlayer) {
        allPlayers.push({ ...player, team: 'blue' })
    }
    for (const player of props.rightPlayer) {
        allPlayers.push({ ...player, team: 'red' })
    }
    
    // 计算结算积分
    const playersWithScores = calculatePlayerScores(
        allPlayers,
        props.messages,
        effectiveWinTeam,
        props.pointPool,
        '本局实时预估',
        false
    )
    
    // 创建玩家ID到结算积分的映射
    const scoreMap = new Map<string, number>()
    for (const player of playersWithScores) {
        scoreMap.set(player.player_id, player.finalScore)
    }
    
    return scoreMap
})

// 合并和排序玩家数据（使用最终积分）
const allPlayers = computed(() => {
    switch (props.leaderboardType) {
        case 'season':
            return seasonLeaderboardData.value.sort((a: any, b: any) => a.rank - b.rank)
        case 'week':
            return weekLeaderboardData.value.sort((a: any, b: any) => a.rank - b.rank)
        case 'game':
            // 本局排行榜使用结算积分排序
            const players = [...props.leftPlayer, ...props.rightPlayer]
            const scoresMap = gameLeaderboardScores.value
            return players.map(player => ({
                ...player,
                finalScore: scoresMap.get(player.player_id) || 0,
                points: scoresMap.get(player.player_id) || 0 // 新增：同步finalScore到points
            })).sort((a, b) => (b as any).finalScore - (a as any).finalScore)
        case 'settlement':
            if (props.winTeam && props.messages.length > 0) {
                const playersWithFinalScores = calculateFinalScores()
                return playersWithFinalScores.map(player => ({
                    ...player,
                    points: player.finalScore // 同步finalScore到points
                })).sort((a, b) => (b as any).finalScore - (a as any).finalScore)
            } else {
                return []
            }
    }
})

// 分页相关
const currentPage = ref(0)
const playersPerPage = 7
const totalPages = computed(() => Math.ceil(allPlayers.value.length / playersPerPage))

// 当前页显示的玩家
const currentPagePlayers = computed(() => {
    const start = currentPage.value * playersPerPage
    const end = start + playersPerPage
    return allPlayers.value.slice(start, end)
})

function goToPage(p: number) {
    if (p === currentPage.value) return
    if (p < 0 || p >= totalPages.value) return
    currentPage.value = p
    stopAutoScroll()
    startAutoScroll()
}

// 切换按钮：可通过 CSS 变量单独控制定位与透明度
function switchButtonStyle(name: 'season' | 'week' | 'game') {
    const n = String(name)
    return {
        position: 'absolute',
        left: `var(--lb-switch-${n}-left, 1060px)`,
        top: `var(--lb-switch-${n}-top, 80px)`,
        width: `var(--lb-switch-${n}-width, 90px)`,
        height: `var(--lb-switch-${n}-height, 36px)`,
        opacity: `var(--lb-switch-${n}-opacity, 0.9)`,
        zIndex: 1006,
    } as any
}

function switchType(type: 'season' | 'week' | 'game') {
    if (props.leaderboardType === type) return
    stopAutoScroll()
    currentPage.value = 0
    // 通知父组件切换展示类型
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    emit('update:leaderboardType', type)
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    emit('change-leaderboard-type', type)
}

// 数值计算辅助函数
const getUnitsValue = (player: any) => {
    if (props.leaderboardType === 'season' || props.leaderboardType === 'week') {
        return (player as any).points || 0
    }
    return player.units || 0
}

const getScoreValue = (player: any) => {
    if (props.leaderboardType === 'season' || props.leaderboardType === 'week') {
        return (player as any).points || 0
    }
    if (props.leaderboardType === 'game') {
        return (player as any).finalScore || 0
    }
    if (props.leaderboardType === 'settlement' && 'finalScore' in player) {
        return (player as any).finalScore
    }
    if (props.winTeam && props.messages.length > 0 && 'finalScore' in player) {
        return (player as any).finalScore
    }
    return player.score !== undefined ? player.score : (player.sortValue || 0)
}

// 生成鲜艳的随机颜色数组
const generateRandomColors = () => {
    const vibrantColors = [
        { r: 255, g: 99, b: 132 },   // 亮红
        { r: 54, g: 162, b: 235 },   // 亮蓝
        { r: 255, g: 205, b: 86 },   // 亮黄
        { r: 75, g: 192, b: 192 },   // 青色
        { r: 153, g: 102, b: 255 },  // 紫色
        { r: 255, g: 159, b: 64 },   // 橙色
        { r: 199, g: 199, b: 199 },  // 灰色
        { r: 83, g: 102, b: 255 },   // 靛蓝
        { r: 255, g: 99, b: 255 },   // 粉色
        { r: 99, g: 255, b: 132 }    // 绿色
    ]
    return vibrantColors
}

const rowColors = reactive(generateRandomColors())

// 自动分页滚动
const autoScroll = ref<number | null>(null)
const closeTimeout = ref<number | null>(null);

const startAutoScroll = () => {
    // 统一处理所有排行榜类型
    if (totalPages.value <= 1) {
        // 单页情况：显示一段时间后自动关闭
        closeTimeout.value = setTimeout(() => {
            emit('display-completed', [])
        }, 12000)
        return
    }

    autoScroll.value = setInterval(() => {
        if (currentPage.value + 1 < totalPages.value) {
            // 还有下一页，继续翻页
            currentPage.value = currentPage.value + 1
        } else {
            // 已经是最后一页，显示完后自动关闭排行榜
            stopAutoScroll()
            emit('display-completed', [])
        }
    }, 12000)
}

const stopAutoScroll = () => {
    if (autoScroll.value) {
        clearInterval(autoScroll.value)
        autoScroll.value = null
    }
    if (closeTimeout.value) {
        clearTimeout(closeTimeout.value);
        closeTimeout.value = null;
    }
}

// 计算最终的显示状态（指令状态优先级最高）
const shouldShowContent = computed(() => {
    return isDirectiveVisible.value && props.visible
})

// 统一的刷新函数，处理所有显示逻辑
const refreshDisplay = async () => {
    displayCycleId.value++; // 每次刷新都创建一个新的周期
    const currentCycleId = displayCycleId.value;

    stopAutoScroll(); // 停止任何之前的计时器

    if (shouldShowContent.value) {
        currentPage.value = 0;

        if (props.leaderboardType === 'season') {
            await fetchSeasonLeaderboard();
        } else if (props.leaderboardType === 'week') {
            await fetchWeekLeaderboard();
        }

        // 如果在数据获取期间，用户切换了模式，则中止后续操作
        if (currentCycleId !== displayCycleId.value) return;

        nextTick(() => {
            startAutoScroll();
        });
    }
};

// 监听显示状态和排行榜类型的变化，触发刷新
watch(() => [shouldShowContent.value, props.leaderboardType], async (newValue, oldValue) => {
        const [shouldShow, newType] = newValue;
        const [wasShowing, oldType] = oldValue || [];
        
        if (shouldShow) {
            if (!wasShowing || newType !== oldType) {
                await refreshDisplay();
                topPlayers.value = allPlayers.value.slice(0, 3).map(item => toRaw(item));
            }
        } else {
            // 隐藏时清理
            stopAutoScroll();
        }
}, { immediate: true, deep: true });

// 监听从赛季切换回其他模式时，清理赛季数据
watch(() => props.leaderboardType, (newType, oldType) => {
    if (oldType === 'season' && newType !== 'season') {
        seasonLeaderboardData.value = [];
        currentSeasonNumber.value = null;
    }
    if (oldType === 'week' && newType !== 'week') {
        weekLeaderboardData.value = [];
        currentWeekRange.value = null;
    }
});

const handleMessage = async (message: any) => {
    let { type, scope } = message;
    switch (type) {
        case 'settle':
            await nextTick();
            if (allPlayers.value.length > 0) {
                await nextTick();
                const playerResults = generatePlayerResults();
                if (playerResults && playerResults.length > 0) {
                    try {
                        await postApi.updatePointsMilitary(playerResults)
                        await postApi.updateCountry(playerResults)
                    } catch (_) {
                    }
                }
            }
            break;
    }
}

onMounted(() => {
    eventBus.on('socket-message', message => handleMessage(message));
})

onUnmounted(() => {
    stopAutoScroll()
})

// 计算进度条缩放比例
const calculateProgressScale = (units: number, leaderboardType?: string) => {
    if (units <= 0) {
        return 0
    }

    // 有单位数的情况下，最少显示1%的进度条
    const minVisibleScale = 0.01 // 最小可见进度条比例(1%)
    const maxScale = 1.0 // 最大进度条比例(100%)

    // 进度条满值统一为 10000（1w）
    const maxValue = 10000

    // 计算实际占比
    const actualRatio = Math.min(1, units / maxValue)

    // 将实际占比映射到 1%-100% 的范围
    const mappedScale = minVisibleScale + (maxScale - minVisibleScale) * actualRatio

    return mappedScale
}
</script>

<style scoped lang="less">
@import '@/assets/xinJi/css/Leaderboard.less';
</style>
